﻿using System;

namespace NPack.Interfaces
{
    /// <summary>
    /// Enumeration of precision modes
    /// </summary>
    public enum PrecisionMode
    {
        /// <summary>
        /// Precision is that of an integer
        /// </summary>
        ToFixed,

        /// <summary>
        /// Precision is maximum - dependant on the type of the component or its scalar - that of <see cref="T:System.Single"/>
        /// </summary>
        ToSingle,

        /// <summary>
        /// Precision is maximum - dependant on the type of the component or its scalar - that of <see cref="T:System.Double"/>
        /// </summary>
        ToDouble,

        /// <summary>
        /// Precision is maximum - dependant on the type of the component or its scalar - that of <see cref="T:System.Decimal"/>
        /// </summary>
        ToDecimal
    }

    /// <summary>
    ///
    /// </summary>
    /// <typeparam name="TComponent">The type of the component</typeparam>
    public interface IPrecisable<TComponent> : IRoundable<TComponent>
    {
        /// <summary>
        /// Returns an precised instance or value
        /// </summary>
        /// <param name="precisionMode"></param>
        /// <returns></returns>
#if DOTNET40

        [System.Diagnostics.Contracts.Pure]
#endif
        TComponent MakePrecise(PrecisionMode precisionMode);

        /// <summary>
        /// Returns an precised instance or value
        /// </summary>
        /// <param name="precisionMode">The precision mode</param>
        ///<param name="roundingMode">The rounding mode</param>
        /// <returns>The precised value</returns>
#if DOTNET40

        [System.Diagnostics.Contracts.Pure]
#endif
        TComponent MakePrecise(PrecisionMode precisionMode, RoundingMode roundingMode);

        /// <summary>
        /// Returns an precised instance or value
        /// </summary>
        /// <param name="precisionMode">The precision mode</param>
        ///<param name="decimals">The number of decimals</param>
        /// <returns>The precised value</returns>
#if DOTNET40

        [System.Diagnostics.Contracts.Pure]
#endif
        TComponent MakePrecise(PrecisionMode precisionMode, int decimals);

        /// <summary>
        /// Returns an precised instance or value
        /// </summary>
        /// <param name="precisionMode">The precision mode</param>
        ///<param name="roundingMode">The rounding mode</param>
        ///<param name="decimals">The number of decimals</param>
        /// <returns>The precised value</returns>
#if DOTNET40

        [System.Diagnostics.Contracts.Pure]
#endif
        TComponent MakePrecise(PrecisionMode precisionMode, RoundingMode roundingMode, Int32 decimals);
    }
}